package com.tofine.smarthome.fragment;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetDialog;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.query.Select;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.tofine.smarthome.R;
import com.tofine.smarthome.adapter.CategoryRecyclerViewAdapter;
import com.tofine.smarthome.adapter.DeviceRecyclerViewAdapter;
import com.tofine.smarthome.adapter.RoomRecyclerViewAdapter;
import com.tofine.smarthome.base.BaseFragment;
import com.tofine.smarthome.model.Category;
import com.tofine.smarthome.model.Device;
import com.tofine.smarthome.model.Room;
import com.tofine.smarthome.rest.RestClient;
import com.tofine.smarthome.ui.CaptureActivityPortrait;
import com.tofine.smarthome.ui.DeviceInfoActivity;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import info.hoang8f.android.segmented.SegmentedGroup;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * @author ddMax
 * @since 2016/4/25
 * 说明：设备碎片类
 */
public class DeviceFragment extends BaseFragment implements RadioGroup.OnCheckedChangeListener {
    public static final String TAG = DeviceFragment.class.getSimpleName();

    private List<Device> mDeviceData;
    private List<Category> mCategoryData;
    private List<Room> mRoomData;

    private View view;
    @Bind(R.id.segmented) SegmentedGroup mSegmentedGroup;
    @Bind(R.id.device_list) RecyclerView mDeviceList;
    @Bind(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
    private RecyclerView.Adapter mAdapter;
    private BottomSheetDialog dialog = null;

    public DeviceFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment DeviceFragment.
     */
    public static DeviceFragment newInstance() {
        DeviceFragment fragment = new DeviceFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_device, container, false);
        initView();
        initData();
        return view;
    }

    @Override
    protected void initView() {
        ButterKnife.bind(this, view);

        // 设置对应的ActionBar
        setUpActionBar();
        // 设置下拉出现小圆圈是否是缩放出现，出现的位置，最大的下拉位置
        mSwipeRefreshLayout.setProgressViewOffset(true, 0, 100);
        // 设置下拉圆圈上的颜色
        mSwipeRefreshLayout.setColorSchemeResources(
                R.color.swipe_blue,
                R.color.swipe_green,
                R.color.swipe_orange,
                R.color.swipe_red
        );
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });
        // 设置SegmentedGroup切换监听
        mSegmentedGroup.setOnCheckedChangeListener(this);

        // 默认第一次进入选中设备Segment
        this.onCheckedChanged(null, R.id.segmented_btn_all);

    }

    @Override
    protected void initData() {
        // 需先初始化类型和房间数据
        if (new Select().from(Category.class).exists()) {
            mCategoryData = new Select().from(Category.class).execute();
            Log.d(TAG, "mCategoryData exists");
        } else {
            getCategoryData();
        }
        if (new Select().from(Room.class).exists()) {
            mRoomData = new Select().from(Room.class).execute();
        }
        if (new Select().from(Device.class).exists()) {
            mDeviceData = new Select().from(Device.class).execute();
            updateSegmentCheckedStatus();
        }

    }

    /**
     * RestClient获取设备数据
     */
    private void getDeviceData() {
        setListShown(false);

        RestClient.getInstance().getApiService().getAllDevices().enqueue(new Callback<List<Device>>() {
            @Override
            public void onResponse(Call<List<Device>> call, Response<List<Device>> response) {
                Log.d(TAG, "/api/devices: " + response.toString());
                mDeviceData = response.body();
                Log.d(TAG, "成功获取mDeviceData: " + mDeviceData.toString());
                // 保存到本地
                ActiveAndroid.beginTransaction();
                try {
                    for (Device device : mDeviceData) {
                        // TODO: 需重新设置对应Category, Room外键?
                        device.category = new Select().from(Category.class).where("_id = '" + device.category._id + "'").executeSingle();
                        device.room = new Select().from(Room.class).where("_id = '" + device.room._id + "'").executeSingle();
                        device.save();
                    }
                    ActiveAndroid.setTransactionSuccessful();
                } finally {
                    ActiveAndroid.endTransaction();
                    // 调用以刷新UI
                    onAllDataRetrieved();
                }
            }

            @Override
            public void onFailure(Call<List<Device>> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    /**
     * RestClient获取类型数据
     */
    private void getCategoryData() {
        setListShown(false);

        RestClient.getInstance().getApiService().getAllCategories().enqueue(new Callback<List<Category>>() {
            @Override
            public void onResponse(Call<List<Category>> call, Response<List<Category>> response) {
                mCategoryData = response.body();
                Log.d(TAG, "成功获取mCategoryData: " + mCategoryData.toString());
                // 保存到本地
                ActiveAndroid.beginTransaction();
                try {
                    for (Category category : mCategoryData) {
                        category.save();
                    }
                    ActiveAndroid.setTransactionSuccessful();
                } finally {
                    ActiveAndroid.endTransaction();
                    // 再请求Room
                    if (new Select().from(Room.class).exists()) {
                        mRoomData = new Select().from(Room.class).execute();
                        Log.d(TAG, "mRoomData exists");
                    } else {
                        getRoomData();
                    }
                }
            }

            @Override
            public void onFailure(Call<List<Category>> call, Throwable t) {

            }
        });
    }

    /**
     * RestClient获取房间数据
     */
    private void getRoomData() {
        setListShown(false);

        RestClient.getInstance().getApiService().getAllRooms().enqueue(new Callback<List<Room>>() {
            @Override
            public void onResponse(Call<List<Room>> call, Response<List<Room>> response) {
                mRoomData = response.body();
                Log.d(TAG, "成功获取mRoomData: " + mRoomData.toString());
                try {
                    ActiveAndroid.beginTransaction();
                    for (Room room : mRoomData) {
                        room.save();
                    }
                    ActiveAndroid.setTransactionSuccessful();
                } finally {
                    ActiveAndroid.endTransaction();
                    // 再获取所有设备
                    if (new Select().from(Device.class).exists()) {
                        // 本地存在数据
                        mDeviceData = new Select().from(Device.class).execute();
                        onAllDataRetrieved();
                        Log.d(TAG, "mDeviceData exists");
                    } else {
                        getDeviceData();
                    }
                }
            }

            @Override
            public void onFailure(Call<List<Room>> call, Throwable t) {

            }
        });
    }

    /**
     * 当所有数据获取到后，即获取到设备数据后
     */
    public void onAllDataRetrieved() {
        setListShown(true);
        int segmentedId = mSegmentedGroup.getCheckedRadioButtonId();
        this.onCheckedChanged(null, segmentedId);
    }

    /**
     * 设置DeviceList显示状态
     *
     * @param finishLoading 是否显示
     */
    private void setListShown(boolean finishLoading) {
        mDeviceList.setVisibility(finishLoading ? View.VISIBLE : View.GONE);
        if (finishLoading || !mSwipeRefreshLayout.isRefreshing()) {
            mSwipeRefreshLayout.setRefreshing(!finishLoading);
        }
    }

    @Override
    protected void setUpActionBar() {
        super.setUpActionBar();
        // 设置标题
        mTvActionBarTitle.setText(getString(R.string.title_fragment_segment_device));
        // 设置添加设备按钮点击监听
        ImageView btnAddDevice = (ImageView) mActionBar.getCustomView().findViewById(R.id.btn_add_device);
        btnAddDevice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showAddDeviceDialog();
            }
        });
    }

    /**
     * 初始化并显示添加设备对话框
     */
    private void showAddDeviceDialog() {
        if (dialog == null) {
            dialog = new BottomSheetDialog(getActivity());
        }
        if (!dialog.isShowing()) {
            dialog = new BottomSheetDialog(getActivity());
            View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_add_device, null);
            Button btnScan = (Button) view.findViewById(R.id.btn_qrcode);
            btnScan.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    IntentIntegrator scanIntegrator = IntentIntegrator.forSupportFragment(DeviceFragment.this);
                    scanIntegrator.setCaptureActivity(CaptureActivityPortrait.class);
                    scanIntegrator.setOrientationLocked(false);
                    scanIntegrator.initiateScan();
                }
            });
            dialog.setContentView(view);
            dialog.show();
        }
    }

    /**
     * 处理SegmentedGroup切换时RecyclerView中的数据
     *
     * @param group
     * @param checkedId
     */
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.segmented_btn_all:
                if (mDeviceData != null) {
                    mAdapter = new DeviceRecyclerViewAdapter(getActivity(), mDeviceData);
                }
                break;
            case R.id.segmented_btn_category:
                if (mCategoryData != null) {
                    mAdapter = new CategoryRecyclerViewAdapter(getActivity(), mCategoryData);
                }
                break;
            case R.id.segmented_btn_room:
                if (mRoomData != null) {
                    mAdapter = new RoomRecyclerViewAdapter(getActivity(), mRoomData);
                }
                break;
        }
        mDeviceList.setLayoutManager(new LinearLayoutManager(getActivity()));
        mDeviceList.setAdapter(mAdapter);
    }

    /**
     * 获取到数据后刷新视图
     */
    private void updateView() {
        int segmentedId = mSegmentedGroup.getCheckedRadioButtonId();

    }

    public void updateSegmentCheckedStatus() {
        int segmentedId = mSegmentedGroup.getCheckedRadioButtonId();
        this.onCheckedChanged(null, segmentedId);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if (result != null) {
            if (result.getContents() == null) {
                Log.d(TAG, "Scan cancelled!");
            } else {
                Log.d(TAG, "Scanned successfully: " + result.getContents());
                Intent intent = new Intent(getActivity(), DeviceInfoActivity.class);
                Bundle bundle = new Bundle();
                bundle.putInt("mode", DeviceInfoActivity.MODE_ADD);
                bundle.putString("scanResult", result.getContents());
                intent.putExtras(bundle);
                startActivityForResult(intent, DeviceInfoActivity.MODE_ADD);
            }
            dialog.cancel();
        } else {
            switch (requestCode) {
                case DeviceInfoActivity.MODE_ADD:
                    if (resultCode == Activity.RESULT_OK) {
                        Bundle bundle = data.getExtras();
                        final Device device = (Device) bundle.getSerializable("new_device");
                        if (device != null) {
                            device.status = false;
                            device.isFavorite = false;
                            device.setCategory(device.category.name);
                            device.room = new Select().from(Room.class)
                                    .where("name='" + bundle.getString("new_device_room_name") + "'").executeSingle();
                            device.save();

                            // POST请求
                            postDeviceData(device);

                        }
                    }
                    break;
            }
        }
    }

    /**
     * POST请求创建设备
     *
     * @param device Device实体类
     */
    private void postDeviceData(final Device device) {
//        Gson gson = new GsonBuilder()
//                .registerTypeAdapter(Category.class, new CategoryTypeAdapter())
//                .registerTypeAdapter(Room.class, new RoomTypeAdapter())
//                .registerTypeAdapter(Device.class, new DeviceTypeAdapter())
//                .create();
//        Log.d(TAG, gson.toJson(device));
        final ProgressDialog dialog = new ProgressDialog(getActivity());
        dialog.setMessage("正在同步设备数据");
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();

        RestClient.getInstance().getApiService().createDevice(device).enqueue(new Callback<Device>() {
            @Override
            public void onResponse(Call<Device> call, Response<Device> response) {
                dialog.cancel();
                Toast.makeText(getActivity(), "设备: " + device.name + " 添加成功", Toast.LENGTH_SHORT).show();
                mDeviceData.add(device);
                updateSegmentCheckedStatus();
            }

            @Override
            public void onFailure(Call<Device> call, Throwable t) {
                dialog.cancel();
                t.printStackTrace();
                Toast.makeText(getActivity(), "网络请求失败", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        if (mAdapter instanceof CategoryRecyclerViewAdapter) {
            ((CategoryRecyclerViewAdapter) mAdapter).onSaveInstanceState(savedInstanceState);
        }
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if (mAdapter instanceof CategoryRecyclerViewAdapter) {
            ((CategoryRecyclerViewAdapter) mAdapter).onRestoreInstanceState(savedInstanceState);
        }
    }

}
